因為函數是Javascript世界的第一等公民,指的是函數與其他數據類型一樣,處於平等地位,可以賦值給其他變數,也能作為參數傳入另一個函數,或者作為別的函數的返回值。
function funcA() {
console.log("函數的聲明型態")
}
--> 調用方式 funcA(), (Function funcA()...)()
//表達式(一)
let funcB = function() {
console.log("函數的表達型態")
}
--> 調用方式 funcB(), (funcB)()
//表達式(二)
(function() { console.log("函數的表達型態2") })
--> 調用方式 (function() {})()
let funcC = function() {
console.log("函數的嵌套型態")
let funcD = function() {
console.log("函數D嵌套在函數C裡面")
}
}
let funcE = function() {
let a = "funcE"
return function() {
alert("我是以閉包型態存在的函數"+a)
}
}
只有聲明型態的函數才具有提升的特性。至於為什麼會有這種現象,在之後的作用域主題會得到解答。
console.log(funcA); // funcA() {return 0}
console.log(funcB); // undefined
//聲明型態
function funcA() {
return 0
}
//標達型態
let funcB = function() {
return 1
}
上面的代碼等同於 :
let funcB
function funcA() {
return 0
}
console.log(funcA); // funcA() {return 0}
console.log(funcB); // undefined
funcB = function() {
return 1
}
另外再看一個例子:
console.log(a); // undefined
console.log(b); // 報錯,b is not defined
var a = 123;
let b = 456;
原因在於ES6提供了let,可以避免hoisting的問題發生。
IIFE(Immediately-invoked Function Expression,立即執行函數)為函數的一種調用方式,非常適合匿名函數調用。
(function() {
conosole.log("我是立即運行的匿名函數")
})();
(function() {
console.log("我也是立即運行的匿名函數")
}())
那既然有了IIFE,為何要有具名函數?
(function funcName(i) {
console.log(`函數名為${funcName.name},第${i}次調用`)
if(i<3) { //遞歸出口
funcName(++i) //遞歸
}
})(1)
//函數名為funcName,第1次調用
//函數名為funcName,第2次調用
//函數名為funcName,第3次調用
如果某個函數可以接收另一個函數作為參數,該函數就稱為高階函數。
function fn1(callback) {
if(callback){
callback();
}
}
fn1(function() {
alert("高階函數")
})